package storage

import (
	"context"
	"fmt"
	"WchimeGinSystem/conf"
	"WchimeGinSystem/utils"
	"io"
	"log"
	"path/filepath"
	"strings"
	"time"

	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
)

var MinioClientGlobal *MinioClient

type MinioClient struct {
	Client *minio.Client
}

func (m *MinioClient) UploadFile(file io.Reader, bucket string, path_name string, ContentType string) error {
	var opt *minio.PutObjectOptions
	if ContentType != "" {
		opt = &minio.PutObjectOptions{ContentType: MyContentType["png"]}
	} else {
		opt = &minio.PutObjectOptions{ContentType: MyContentType[ContentType]}
	}
	// 上传文件到存储桶
	_, err := m.Client.PutObject(context.Background(), bucket, path_name, file, -1, *opt)
	if err != nil {
		log.Println("上传文件失败: ", err)
		return err
	}
	return nil
}

func (m *MinioClient) GetFile(bucketName, objectName string) (*minio.Object, error) {
	// 下载存储桶中的文件

	object, err := m.Client.GetObject(context.Background(), bucketName, objectName, minio.GetObjectOptions{})
	if err != nil {
		log.Println("获取文件失败: ", err)
		return nil, err
	}

	return object, nil
}

// GetPresignedGetObject 返回对象的url地址，有效期时间为expires
func (m *MinioClient) GetPresignedGetObject(bucketName string, objectName string, expires time.Duration) (string, error) {

	object, err := m.Client.PresignedGetObject(context.Background(), bucketName, objectName, expires, nil)
	if err != nil {
		log.Println("获取文件失败: ", err)
		return "", err
	}

	return object.String(), nil
}

// 删除对象
func (m *MinioClient) RemoveFile(bucketName string, objectName string) error {
	opt := minio.RemoveObjectOptions{}
	err := m.Client.RemoveObject(context.Background(), bucketName, objectName, opt)
	if err != nil {
		log.Println("删除文件失败: ", err)
		return err
	}

	return nil
}

// ----------------------------------------------------------

// NewMinioClient 初始化minio
func NewMinioClient() (*MinioClient, error) {
	// 初始化 Minio 客户端
	endpoint := fmt.Sprintf("%s:%s", conf.MINIO_HOST, conf.MINIO_PORT)
	minioClient, err := minio.New(endpoint, &minio.Options{
		Creds:  credentials.NewStaticV4(conf.MINIO_USER, conf.MINIO_PWD, ""),
		Secure: conf.MINIO_SECURE,
	})
	if err != nil {
		log.Println("Minio链接失败: ", err)
		return nil, err
	}
	client := &MinioClient{
		Client: minioClient,
	}
	MinioClientGlobal = client
	return MinioClientGlobal, nil
}

func MinioUpload(file io.Reader, file_name string, forlder_path string, ContentType string) (string, error) {

	name_li := strings.Split(file_name, ".")
	file_type := name_li[len(name_li)-1]
	time_name := utils.GetTimeString()
	new_file_name := time_name + "." + file_type
	put_path := filepath.Join(forlder_path, new_file_name)
	put_path = strings.ReplaceAll(put_path, "\\", "/")
	client, err := NewMinioClient()
	if err != nil {
		return "", err
	}
	err = client.UploadFile(file, conf.MINIO_BUCKET, put_path, ContentType)
	return put_path, err
}

func MinioGetFile(file_name string) (*minio.Object, error) {
	client, err := NewMinioClient()
	if err != nil {
		return nil, err
	}
	return client.GetFile(conf.MINIO_BUCKET, file_name)
}

func MinioGetURL(file_name string) (string, error) {
	client, err := NewMinioClient()

	if err != nil {
		return "", err
	}
	return client.GetPresignedGetObject(conf.MINIO_BUCKET, file_name, time.Duration(300)*time.Second)
}

func MinioDelFile(file_name string) error {
	client, err := NewMinioClient()

	if err != nil {
		return err
	}
	return client.RemoveFile(conf.MINIO_BUCKET, file_name)
}
